package shaw.wifi.encryption;

import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


public class RsaEncryption {
	private BigInteger mod;
	private BigInteger exp;
	private PrivateKey privateKey;
	private PublicKey publicKey;
	
	private Cipher rsaCipher;
	
	static {
		 Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
	}
	
	public RsaEncryption() {
		initRsa();
	}
	
	private void initRsa() {
		if(rsaCipher == null) {
			try {
				rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (NoSuchPaddingException e) {
				e.printStackTrace();
			} catch (NoSuchProviderException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			generateKeys();
		}
	}

	public void generateKeys() {
		try {
			KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "BC");
			kpg.initialize(2048, new SecureRandom());
			KeyPair kp = kpg.generateKeyPair();
			privateKey = kp.getPrivate();
			publicKey = kp.getPublic();
			
			KeyFactory keyFact = KeyFactory.getInstance("RSA", "BC");
			RSAPublicKeySpec pubSpec = (RSAPublicKeySpec) keyFact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
			mod = pubSpec.getModulus();
			exp = pubSpec.getPublicExponent();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public byte[] getMod() {
		return mod.toByteArray();
	}
	public byte[] getExp() {
		return exp.toByteArray();
	}
	
	public byte[] decryptRsa(byte[] cryptBytes) {
		try {
			rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
			return rsaCipher.doFinal(cryptBytes);
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

	public byte[] encryptRsa(byte[] bytes) {
		try {
			rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
			return rsaCipher.doFinal(bytes);
		} catch (InvalidKeyException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (BadPaddingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}
}
